package com.david.http.http.interceptor

import android.text.TextUtils
import android.util.Log
import com.alibaba.fastjson.JSONObject
import com.google.gson.Gson
import okhttp3.Interceptor
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.ResponseBody
import java.io.IOException


class TokenInterceptor:Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        // 获取请求
        // 获取请求
        val request: Request = chain.request()
        // 获取响应
        // 获取响应
        var response = chain.proceed(request)
        // 在这里判断是不是是token失效
        // 当然，判断条件不会这么简单，会有更多的判断条件的
        // 在这里判断是不是是token失效
        // 当然，判断条件不会这么简单，会有更多的判断条件的
        if (response.code == 400) {
            val responseBody = response.body!!.string()
            val mediaType: MediaType?
            mediaType = if (response.body != null && response.body!!.contentType() != null) {
                response.body!!.contentType()
            } else {
                "application/json;charset=utf-8".toMediaTypeOrNull()
            }
            val fResult: FResult = Gson().fromJson(responseBody, FResult::class.java)
            //response.body().string() 只能调用一次   就会close  所以要重建response
            response = response.newBuilder()
                .body(ResponseBody.create(mediaType, responseBody))
                .build()
            if (fResult.getStatus().equals("4001")) {
                // 这里应该调用自己的刷新token的接口
                // 这里发起的请求是同步的，刷新完成token后再增加到header中
                // 这里抛出的错误会直接回调 onError
                val token: String = refreshToken()
                if (!TextUtils.isEmpty(token)) {
                    // 创建新的请求，并增加header
                    val retryRequest: Request = chain.request()
                        .newBuilder()
                        .header("Authorization", getToken())
                        .build()

                    // 再次发起请求
                    return chain.proceed(retryRequest)
                }
            }
        }

        return response
    }

    private fun refreshToken(): String {
        var newtoken: String? = null

        /**
         * 必须使用同步请求
         */
        val JSON = "application/json;charset=utf-8".toMediaTypeOrNull()
        //Log.e("OkHttpManager", "重新请求---$url")
        val client = OkHttpClient()
        val map: MutableMap<String, Any> = HashMap()
        map["accessToken"] = getToken()
        map["refreshToken"] = getRefreshToken()
        val jsonObject = JSONObject(map)
        val requestBody: RequestBody = RequestBody.create(JSON, jsonObject.toString())
        val request: Request = Request.Builder().url("url").post(requestBody).build()
        val call = client.newCall(request)
        try {
            val response = call.execute()

            //            FLog.i("HttpLog", "refreshToken response=" + response.body().string());//只能有效调用一次,不能打印
            val credentialDTO: CredentialDTO = Gson().fromJson(response.body!!.string(), CredentialDTO::class.java)
            if (null != credentialDTO.accessToken && null != credentialDTO.refreshToken) {
                newtoken = credentialDTO.accessToken
                TokenManager.getInstance().setAccessToken(credentialDTO.accessToken)
                TokenManager.getInstance().setRefreshToken(credentialDTO.refreshToken)
                //FLog.i("HttpLog", "refreshToken accessToken==" + credentialDTO.accessToken)
            } else {
                newtoken = ""
            }
        } catch (e: IOException) {
            e.printStackTrace()
            newtoken = ""
        }
        return newtoken ?: ""
    }

    private fun getToken(): String {
        return TokenManager.getInstance().getAccessToken()
    }

    private fun getRefreshToken(): String {
        return TokenManager.getInstance().getRefreshToken()
    }

}

class FResult() {
    fun getStatus():Int {
        return 0
    }
}

data class CredentialDTO(
    var accessToken: String? = null,
    var refreshToken: String? = null,
)

class TokenManager{
    fun setAccessToken (token: String?){

    }
    fun getAccessToken (): String{
        return ""
    }

    fun setRefreshToken(token: String?) {

    }

    fun getRefreshToken() : String {
        return ""
    }

    companion object{
        fun getInstance(): TokenManager {
            return TokenManager()
        }
    }
}